﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using CodeMadeSimple.Common.Validation;

namespace EnvRide.Core.ObjectModel
{
    public abstract class ObjectWithIncludes : IValidatable
    {
        private AttributeOverrideIncludeCollection _includedAttributeOverrides;
        private ElementOverrideIncludeCollection _includedElementOverrides;
        
        /// <summary>
        /// List of attributes overrides inclusions added to all environment.
        /// </summary>
        public AttributeOverrideIncludeCollection IncludedAttributeOverrides
        {
            get { return _includedAttributeOverrides; }
            set { _includedAttributeOverrides = value; }
        }

        /// <summary>
        /// List of elements overrides inclusions added to all environment.
        /// </summary>
        public ElementOverrideIncludeCollection IncludedElementOverrides
        {
            get { return _includedElementOverrides; }
            set { _includedElementOverrides = value; }
        }

        protected void WriteIncludesXml(XmlWriter writer)
        {
            if (_includedAttributeOverrides != null)
            {
                writer.WriteStartElement("IncludedAttributeOverrides");

                foreach (OverrideInclude overInc in _includedAttributeOverrides)
                {
                    writer.WriteStartElement("OverrideInclude");

                    overInc.WriteXml(writer);

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }

            if (_includedElementOverrides != null)
            {
                writer.WriteStartElement("IncludedElementOverrides");

                foreach (OverrideInclude overInc in _includedElementOverrides)
                {
                    writer.WriteStartElement("OverrideInclude");

                    overInc.WriteXml(writer);

                    writer.WriteEndElement();
                }

                writer.WriteEndElement();
            }
        }

        protected void ReadIncludedAttributesOverrides(XmlReader reader)
        {
            _includedAttributeOverrides = new AttributeOverrideIncludeCollection();

            while (reader.Read() && reader.Name != "IncludedAttributeOverrides")
            {
                if (reader.Name.Equals("OverrideInclude"))
                {
                    AttributeOverrideInclude overInc = new AttributeOverrideInclude();

                    overInc.ReadXml(reader);

                    _includedAttributeOverrides.Add(overInc);
                }
            }
        }

        protected void ReadIncludedElementOverrides(XmlReader reader)
        {
            _includedElementOverrides = new ElementOverrideIncludeCollection();

            while (reader.Read() && reader.Name != "IncludedElementOverrides")
            {
                if (reader.Name.Equals("OverrideInclude"))
                {
                    ElementOverrideInclude overInc = new ElementOverrideInclude();

                    overInc.ReadXml(reader);

                    _includedElementOverrides.Add(overInc);
                }
            }
        }

        #region IValidatable Members

        public ValidationResult Validate()
        {
            ValidationResult result = new ValidationResult(this);

            if (_includedAttributeOverrides != null && _includedAttributeOverrides.Count > 0)
            {
                ValidationResult includedAtts = new ValidationResult("IncludedAttributeOverrides");

                foreach (AttributeOverrideInclude attOverInc in _includedAttributeOverrides)
                {
                    includedAtts.AddChildResult(attOverInc.Validate());
                }

                result.AddChildResult(includedAtts);
            }

            if (_includedElementOverrides != null && _includedElementOverrides.Count > 0)
            {
                ValidationResult includedElems = new ValidationResult("IncludedElementOverrides");

                foreach (ElementOverrideInclude attOverInc in _includedElementOverrides)
                {
                    includedElems.AddChildResult(attOverInc.Validate());
                }

                result.AddChildResult(includedElems);
            }

            AddValidationMessages(result);

            return result;
        }

        protected virtual void AddValidationMessages(ValidationResult result)
        {

        }

        public abstract string GetValidationId();

        #endregion
    }
}
